package com.bow.demo.module.zookeeper.curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.CuratorWatcher;
import org.apache.curator.utils.CloseableUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.TimeUnit;

/**
 *
 * ZkDemo
 *
 * @author vv
 * @since 2016/9/14.
 */
public class CuratorDemo {

    private CuratorFramework client = null;

    @Before
    public void setup() {
        client = ClientFactory.newClient();
    }

    @After
    public void destroy() {
        CloseableUtils.closeQuietly(client);
    }

    @Test
    public void show() throws Exception {

        String path = "/test";
        // create
        client.create().forPath(path, "vv".getBytes());
        byte[] bs = client.getData().forPath(path);
        System.out.println("data : " + new String(bs)); // vv

        // update
        client.setData().forPath(path, "vv1".getBytes());
        byte[] bs2 = client.getData().forPath(path);
        System.out.println("changed : " + new String(bs2)); // vv1

        // delete
        client.delete().forPath(path);
        Stat stat = client.checkExists().forPath(path);
        System.out.println(stat); // null
    }

    @Test
    public void testEphemeral() throws Exception {
        String path = "/instance";
        client.create().withMode(CreateMode.PERSISTENT).forPath(path);
        attachWatcher(path);
        // watcher被触发2次
        client.create().withMode(CreateMode.PERSISTENT).forPath(path + "/service1");
        client.create().withMode(CreateMode.PERSISTENT).forPath(path + "/service2");
        // 添加一个临时节点
        client.create().withMode(CreateMode.EPHEMERAL).forPath(path + "/service1" + "/url1");

        TimeUnit.SECONDS.sleep(30);
    }

    /**
     * 共2种类型监听，子节点监听器和数据监听器
     * 
     * @param path
     * @throws Exception
     */
    public void attachWatcher(final String path) throws Exception {
        CuratorWatcher curatorWatcher = new CuratorWatcher() {
            @Override
            public void process(WatchedEvent event) throws Exception {
                System.out.println(event.getPath() + ">>" + event.getType());
                // 重新给path添加子节点监视器
                client.getChildren().usingWatcher(this).forPath(event.getPath());
            }
        };
        // 监视path的子节点变化
        client.getChildren().usingWatcher(curatorWatcher).forPath(path);
        // 监视path节点数据变化
        // client.getData().usingWatcher(curatorWatcher).forPath(path);
    }

    @Test
    public void delete() throws Exception {
        // 强制删除所有节点
        client.delete().deletingChildrenIfNeeded().forPath("/instance");
    }

}